package com.daniel.juc.lock;

/**
 * 生产者消费者Synchronized
 * 线程之间的通信问题：等待唤醒，通知唤醒
 * 线程交替执行 A B 操作同一个变量 num=0
 * A num+1
 * B num-1
 *
 * @author Daniel
 * @version V1.0
 * @date 2020/5/18 11:05
 */
public class PcDemo01 {
	public static void main(String[] args) {
		Data data = new Data();

		new Thread(() -> {
			for (int i = 0; i < 10; i++) {
				try {
					data.increment();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "A").start();

		new Thread(() -> {
			for (int i = 0; i < 10; i++) {
				try {
					data.decrement();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "B").start();

		new Thread(() -> {
			for (int i = 0; i < 10; i++) {
				try {
					data.increment();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "C").start();

		new Thread(() -> {
			for (int i = 0; i < 10; i++) {
				try {
					data.decrement();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}, "D").start();
	}

}

/**
 * 判断等待，业务，通知
 * 数字资源类
 */
class Data {
	private int number = 0;

	/**
	 * +1操作
	 *
	 * @throws InterruptedException
	 */
	public synchronized void increment() throws InterruptedException {
		while (number != 0) {
			// 等待
			this.wait();
		}

		number++;
		System.out.println(Thread.currentThread().getName() + "=>" + number);
		// 通知其他线程，我+1完毕了
		this.notifyAll();
	}

	/**
	 * -1操作
	 *
	 * @throws InterruptedException
	 */
	public synchronized void decrement() throws InterruptedException {
		while (number == 0) {
			// 等待
			this.wait();
		}
		number--;
		System.out.println(Thread.currentThread().getName() + "=>" + number);
		// 通知其他线程，我-1完毕了
		this.notifyAll();
	}
}
